package com.black.utils.command;

import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import static com.black.utils.commons.constant.JSchConstant.EXEC;
import static com.black.utils.commons.display.IOPrintUtil.print;

/**
 * @author ylx
 */
@Slf4j
@Getter
@Setter
public class LinuxRemoteCmdExecutor extends LinuxLocalCmdExecutor
{
    private String ip;

    private int port;

    private String username;

    private String password;

    private JSch jSch;

    private Session session;

    private int timeout = 6000;

    public LinuxRemoteCmdExecutor(String username, String password, String ip, int port)
        throws JSchException
    {
        this.ip = ip;
        this.port = port;
        this.username = username;
        this.password = password;
        this.jSch = new JSch();
        this.session = jSch.getSession(username, ip, port);
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        this.session.setConfig(config);
        this.session.setTimeout(timeout);
        this.session.setPassword(password);
        this.session.connect();
    }

    @Override
    public boolean exec(String cmd)
    {
        try
        {
            ChannelExec channel = (ChannelExec)session.openChannel(EXEC);
            log.debug("exec [{}]", cmd);
            channel.setCommand(cmd);
            channel.connect();
            if (isPrintOutput)
            {
                print(channel.getErrStream());
                print(channel.getInputStream());
            }
            return channel.getExitStatus() == 0;
        }
        catch (JSchException e)
        {
            log.error("exec [{}] error: {}", cmd, e.getMessage());
        }
        catch (IOException e)
        {
            log.error("get errStream [{}] error: {}", cmd, e.getMessage());
        }
        return false;
    }

    @Override
    public List<String> execute(String cmd)
    {
        List<String> result = new ArrayList<>();
        try
        {
            ChannelExec channel = (ChannelExec)session.openChannel(EXEC);
            log.debug("exec [{}]", cmd);
            channel.setCommand(cmd);
            channel.connect();
            result.addAll(print(channel.getErrStream()));
            result.addAll(print(channel.getInputStream()));
        }
        catch (JSchException e)
        {
            log.error("exec [{}] error: {}", cmd, e.getMessage());
        }
        catch (IOException e)
        {
            log.error("get errStream [{}] error: {}", cmd, e.getMessage());
        }
        return result;
    }
}
